import java.util.Random;

import src.Array;
import src.ArrayQueue;
import src.ArrayStack;
import src.BSTMap;
import src.LinkedList;
import src.LinkedMap;
import src.LinkedQueue;
import src.LinkedSet;
import src.LinkedStack;
import src.LoopQueue;
import src.Map;
import src.MaxHeap;
import src.Queue;
import src.Set;
import src.tree.BST;
import src.tree.Merger;
import src.tree.SegmentTree;
import src.tree.Trie;

/**
 * main
 */
public class useDemo {

    public static void useArray() {
        Array<Integer> arr = new Array<>();
        for (int i = 0; i < 10; i++) {
            arr.addLast(i);
        }
        arr.removeLast();
        System.out.println(arr);
        arr.addFirst(999);
        arr.addFirst(998);
        System.out.println(arr);
        arr.removeLast();
        arr.removeLast();
        arr.removeLast();
        System.out.println(arr);
        Integer[] data = {1, 2, 3, 4, 5, 6, 7, 8};
        Array<Integer> arr2 = new Array<>(data);
        System.out.println(arr2);
    }
    
    public static void useArrayStact() {
        ArrayStack<Integer> st = new ArrayStack<>();
        st.push(1);
        st.push(2);
        st.push(3);
        st.push(4);
        System.out.println(st.pop());
        System.out.println(st.peek());
        System.out.println(st.getSize());
        System.out.println(st);
    }

    public static void useArrayQueue() {
        ArrayQueue<Integer> queue = new ArrayQueue<>();
        queue.enQueue(1);
        queue.enQueue(2);
        queue.enQueue(3);
        queue.enQueue(4);
        queue.enQueue(5);
        System.out.println(queue);
        queue.deQueue();
        queue.deQueue();
        System.out.println(queue);

    }

    public static void useLoopQueue() {
        LoopQueue<Integer> queue = new LoopQueue<>(20);
        queue.enQueue(1);
        queue.enQueue(2);
        queue.enQueue(3);
        queue.enQueue(4);
        queue.enQueue(5);
        System.out.println(queue);
        System.out.println(queue.deQueue());
        System.out.println(queue.deQueue());
        System.out.println(queue);

    }

    public static void useLinkedList(){
        LinkedList<Integer> list = new LinkedList<>();
        for (int i = 0; i < 6; i++) {
            list.addFirst(i);
        }
        System.out.println(list);
        System.out.println(list.getLast());
        list.addLast(999);
        System.out.println(list);
        System.out.println(list.getLast());
        list.remove(0);
        list.removeLast();
        list.addLast(123);
        System.out.println(list);
        System.out.println(list.getLast());
    }

    public static void useLinkedStack() {
        LinkedStack<Integer> st = new LinkedStack<>();
        st.push(1);
        st.push(2);
        st.push(3);
        st.push(4);
        System.out.println(st);
        System.out.println(st.pop());
        System.out.println(st);
        
    }

    public static void useLinkedQueue() {
        Queue<Integer> queue = new LinkedQueue<>();
        for (int i = 0; i < 10; i++)
            queue.enQueue(i);
        System.out.println(queue);
        System.out.println("dequeue:" + queue.deQueue());
        queue.deQueue();
        queue.deQueue();
        queue.enQueue(898);
        queue.enQueue(892);
        queue.enQueue(891);
        System.out.println(queue);
        System.out.println(queue.getSize());
    }

    public static void useBst() {
        BST<Integer> bst = new BST<>();
        int[] nums = {8, 5, 2, 9, 3, 23, 6};
        for (int i : nums) {
            bst.add(i);
        }

        // bst.preOrder();
        // bst.preOrderNR();
        // bst.order();
        // bst.postOrder();
        // System.out.println(bst);
        // bst.levelOrder();
        // System.out.println(bst.min());
        // System.out.println(bst.max());
        // bst.removeMax();
        // bst.removeMin();
        bst.levelOrder();
        bst.remove(9);
        bst.levelOrder();
    }
    public static void useBSTSet () {
        // Set<Integer> set = new BSTSet<>();
        Set<Integer> set = new LinkedSet<>();
        set.add(1);
        set.add(2);
        set.add(3);
        set.add(4);
        set.add(4);
        set.remove(2);
        System.out.println(set.contains(1));
        System.out.println(set.getSize());
    }

    public static void useLinkedMap() {
        Map<String, Integer> map = new LinkedMap<>();
        map.add("aaa", 1);
        map.add("bbb", 2);
        map.add("ccc", 3);
        map.set("aaa", 999);
        System.out.println(map.remove("bbb"));
        System.out.println(map.get("aaa"));
        System.out.println(map);
    }
    public static void useBSTMap() {
        Map<Integer, String> map = new BSTMap<>();
        map.add(5, "123123");
        map.add(4, "123sdasd");
        map.add(6, "123sasfdasd");
        map.add(1, "123sdaaq23sd");
        System.out.println(map);
        map.remove(4);
        System.out.println(map);
    }
    public static void useMaxHeap() {
        MaxHeap<Integer> maxHeap = new MaxHeap<>();
        Random random = new Random();
        for (int i = 0; i < 50; i++) {
            maxHeap.add(random.nextInt(500));
        }
        // Integer[] arr = {1, 4, 5, 2, 8, 8};
        // maxHeap = new MaxHeap<>(arr);
        System.out.println(maxHeap);
        System.out.print("利用大根堆排序：");
        while (! maxHeap.isEmpty()) {
            System.out.print(maxHeap.popMax() +" ");
        }
    }

    public static void useSegTree() {
        Integer[] data = {1, 3, 5, 0, 8, 3};
        SegmentTree<Integer> segTree = new SegmentTree<>(data, (a, b) -> a + b);
        System.out.println(segTree);
        segTree.set(1, 4);
        System.out.println(segTree);
        System.out.println(segTree.query(0, 4));
    }

    public static void useTrie() {
        Trie strSet = new Trie();
        strSet.add("abc");
        strSet.add("ac");
        strSet.add("acggsd");
        strSet.add("asdf");
        strSet.add("yueir");
        System.out.println(strSet.contains("ace"));
        System.out.println(strSet.getSize());
        System.out.println(strSet.serch("as.."));
        System.out.println(strSet.count("ac"));
    }
    public static void main(String[] args) {
        useArray();
        // useArrayStact();
        // useArrayQueue();
        // useLoopQueue();
        // useLinkedList();
        // useLinkedStack();
        // useLinkedQueue();
        // useBst();
        // useBSTSet();
        // useLinkedMap();
        // useBSTMap();
        // useMaxHeap();
        // useSegTree();
        // useTrie();
    }
}
